package pers.kw.server.service;

import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
public class DistributedLockManager {

    @Resource
    private RedissonClient redissonClient;

    public void lock(String lockKey, Runnable task) {
        //todo 参数校验
        RLock rLock = redissonClient.getLock(lockKey);
        try {
            //获取不到锁，会一直阻塞
            rLock.lock();
            //执行业务逻辑
            task.run();
        } finally {
            if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
                log.info("自动释放锁成功");
            }
        }
    }

    /**
     * @param lockKey       锁KEY
     * @param waitTime      抢锁等待时间
     * @param leaseTime     锁过期时间
     * @param unit          时间单位
     * @param task          业务处理
     * @param errorCallBack 获取锁失败，异常回调
     */
    public void tryLock(String lockKey, long waitTime, long leaseTime, TimeUnit unit, Runnable task,
                        Runnable errorCallBack) {
        //todo 参数校验
        RLock rLock = redissonClient.getLock(lockKey);
        try {
            if (rLock.tryLock(waitTime, leaseTime, unit)) {
                //处理业务逻辑
                task.run();
            } else {
                // 处理加锁失败的情况
                errorCallBack.run();
            }
        } catch (InterruptedException e) {
            // 处理加锁时发生的中断异常
            log.error("加锁异常：", e);
        } finally {
            if (rLock.isLocked() && rLock.isHeldByCurrentThread()) {
                rLock.unlock();
                log.info("自动释放锁成功");
            }
        }
    }
}
